package com.myebills.ebpsfrontend.cust.controller;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.ParseException;
import java.util.StringTokenizer;
import java.util.Vector;

import com.myebills.ebpsfrontend.cust.controller.EbppxMyBillsSimulationServlet.LogonException;
import com.myebills.ebpsfrontend.cust.utils.*;
import com.checkfree.isolutions.customer.persist.*;
import com.checkfree.isolutions.admin.ObjectId;
import com.checkfree.isolutions.statement.persist.Statement;
import com.checkfree.isolutions.customer.persist.User;
import com.checkfree.isolutions.customer.persist.UserHomeImpl;
import com.checkfree.isolutions.customer.persist.Merchant;
import com.checkfree.isolutions.customer.persist.MerchantHomeImpl;
import com.checkfree.isolutions.utility.CFiError;
import com.checkfree.isolutions.property.Properties;
import com.checkfree.isolutions.property.PropertiesConfig;
import com.ibm.logging.ILogger;
import com.ibm.logging.IRecordType;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.checkfree.isolutions.security.Cipher;

/**
 * Derive from this class to create a Logon servlet when no session exists.
 * Instance of Template pattern (GOF).
 * Override, doPreTransaction(), authenticateUser(), and doPostTransaction().
 */
public class EbppxMyBillsServlet extends EbppxServlet {

    //possible logon messages
    private static String MSG_SESSION_EXPIRED ="Your session timed out or is invalid";
    private static String MSG_AUTHENTICATION_FAIL ="EBPS Authentication Failure";
    private static String MSG_INVALID_USER ="Invalid User";
    private static String MSG_INVALID_EMAIL ="Invalid User Email";
    private static String MSG_INVALID_ACCOUNT_NO ="Invalid Account Number";
    private static String MSG_INTERNAL_ERROR ="Internal Error";
    private static String MSG_INVALID_ACCESS_IP ="Invalid IP access";


    //Delimiter for the message to get all the tokens
    private static String STR_DELIMITER=",";

    /**
     * Override to perform actions after transaction is completed or rolled back by goSession().
     * When overriding, the convention will be to call super.doPostTransaction()
     * <b>after</b> invoking any other operations that may affect state of servlet.
     */
    protected void doPostTransaction(
    HttpServletRequest req,
    HttpServletResponse res
    ) throws IOException, ServletException {}

    /**
     * Override to perform actions before transaction is completed or rolled back by goSession().
     * When overriding, the convention will be to call super.doPostTransaction()
     * <b>before</b> invoking any other operations that may affect state of servlet.
     */
    protected void doPreTransaction(
    HttpServletRequest req,
    HttpServletResponse res
    ) throws IOException, ServletException {}

    protected class LogonException extends Exception {
        public LogonException(String s) {
            super(s);
        }
    }

    /**
     * Perform decryption for the parameter and some simple validation to the data
     *
     * @param strTimestamp - the timestamp in yyyymmddhhMMss format
     * @param strEncParam - the encrypted parameter containing the detail information
     *
     * @return the object representing the logon user
     * @exception LogonException logon failed
     */
    protected EbppxEcsUser parseParam(HttpServletRequest req)
    throws EbppxMyBillsServlet.LogonException, javax.servlet.ServletException {
        final String fName = "parseParam";

        ILogger trcLogger = getTraceLogger(req);

        if (trcLogger.isLogging())
            trcLogger.entry(IRecordType.TYPE_INFO, this, fName);


        try {
			com.checkfree.isolutions.property.Properties appCfg = com.checkfree.isolutions.property.PropertiesConfig.getApplicationSettings();
        }
        catch (CFiError cfie) {
            if (trcLogger.isLogging())
                trcLogger.text(IRecordType.TYPE_ERROR, this, fName,"CFiError="+cfie);
        }

		String strUserId = "";
		String strAccNo ="";
		String strMsisdn ="";
		String strSimNo ="";
        String passPhase = EbppxConstants.passphrase;
        String encryptedParam = (String)req.getParameter("param");
        
        if(encryptedParam!=null){
	        String param = EncryptionHelper.decrypt(encryptedParam,passPhase);
			System.out.println("param is************************"+param);
	
			StringTokenizer strTok = null;
			if(param != null){
				strTok = new StringTokenizer(param, "&");
			}else{
				throw new LogonException("Invalid parameters.");
			}
			
			int totalToken = strTok.countTokens();
			System.out.println("totalToken is************************"+totalToken);
				//StringTokenizer strTok = new StringTokenizer(param, ",");
			strAccNo = strTok.nextToken();
			strAccNo = strAccNo.split("=")[1];
			System.out.println("strAccNo="+strAccNo);
			strMsisdn = strTok.nextToken();
			strMsisdn = strMsisdn.split("=")[1];
			System.out.println("strMsisdn="+strMsisdn);
			strUserId = strTok.nextToken();
			strUserId = strUserId.split("=")[1];
			System.out.println("strUserId="+strUserId);
		}else{
	        strUserId = EbppxUtil.nullToEmpty(req.getParameter("userId"));
			strAccNo = EbppxUtil.nullToEmpty(req.getParameter("accountNo"));
			strMsisdn = EbppxUtil.nullToEmpty(req.getParameter("msisdn"));
			strSimNo = EbppxUtil.nullToEmpty(req.getParameter("simno"));
		}

        //Split the decypted text into user Id, email and account numbers
        EbppxEcsUser ecsu = new EbppxEcsUser();

        if(!strUserId.equals("")){
			ecsu.setEmail(strUserId);
			ecsu.setUserId(strUserId);
			ecsu.setSAccount(strAccNo);
			ecsu.setMsisdn(strMsisdn);
			ecsu.setSimNo(strSimNo);
		}


        // Get Merchant Name
        String merchantName = "";
        try {
            com.checkfree.isolutions.property.Properties appCfg = com.checkfree.isolutions.property.PropertiesConfig.getApplicationSettings();

            if (appCfg.hasProperty("MerchantName")){
                merchantName = appCfg.getProperty("MerchantName");
                ecsu.setMerchantName(merchantName);
                if (trcLogger.isLogging())
                    trcLogger.text(IRecordType.TYPE_ERROR, this, fName,"Merchant name found : "+merchantName);
            }
        }
        catch (CFiError cfi) {
            if (trcLogger.isLogging())
                trcLogger.text(IRecordType.TYPE_ERROR, this, fName,"Error finding merchant : "+cfi);
        }

        Merchant cfiMerchant = null;
        try {
            cfiMerchant = MerchantHomeImpl.singleton().findByName(ecsu.getMerchantName());
        }
        catch (Throwable e) {
            if (trcLogger.isLogging())
                trcLogger.text(IRecordType.TYPE_ERROR, this, fName,"Error finding merchant : "+e);

            throw new LogonException(MSG_INTERNAL_ERROR);
        }

        if (cfiMerchant == null) {
            if (trcLogger.isLogging())
                trcLogger.text(IRecordType.TYPE_ERROR, this, fName,"Error finding merchant : null");

            throw new LogonException(MSG_INTERNAL_ERROR);
        }

        // Make sure the user is in the DB.
        User cfiUser = null;

        try {
            cfiUser = getUserHome().findByLogonIdAndMerchant(ecsu.getUserId(),cfiMerchant);

            //Create a new user if not found
            if (cfiUser ==null) {
                if (trcLogger.isLogging())
                    trcLogger.text(IRecordType.TYPE_INFO, this, fName,"User not found, creating user : "+ecsu.getUserId());

                try {
                    cfiUser = getUserHome().create(ecsu.getUserId(),cfiMerchant);
                }
                catch (Exception exc) {
                    if (trcLogger.isLogging())
                        trcLogger.text(IRecordType.TYPE_ERROR, this, fName,"Error creating new user : "+exc);

                    throw new LogonException(MSG_INTERNAL_ERROR);
                }
            }
        }
        catch (Throwable t) {
            if (trcLogger.isLogging())
                trcLogger.text(IRecordType.TYPE_ERROR, this, fName,"Error finding user : "+t);

            throw new LogonException(MSG_INTERNAL_ERROR);
        }

        if (cfiUser == null) {
            if (trcLogger.isLogging())
                trcLogger.text(IRecordType.TYPE_ERROR, this, fName,"Error getting user : null");

            throw new LogonException(MSG_INVALID_USER);
        }


        if (trcLogger.isLogging())
            trcLogger.exit(IRecordType.TYPE_INFO, this, fName);

        return ecsu;
    }
	
    /**
     * Connect to i-Series database and begin transaction,
     * and call abstract method <i>authenticateUser<i> to authenticate user.
     * If user is authenticated, redirect browser to URL named by ConstantsURL_LOGON_SUCCESS_PARAM.
     * Otherwise, redirect browser to URL named by Constants.URL_LOGON_FAILURE_PARAM.
     * These may be either request, servlet, or context parameters.
     */
    protected final void doRequest(
    HttpServletRequest req,
    HttpServletResponse res
    ) throws ServletException, java.io.IOException {
        final String fName = "doRequest";
        ILogger trcLogger = getTraceLogger(req);

        if (trcLogger.isLogging())
            trcLogger.entry(IRecordType.TYPE_INFO, this, fName);


        //Begin transaction
        activateISeriesEngine(req, fName);

        try {
            doPreTransaction(req, res);
            beginTransaction(req, fName);

            try {

                req.setAttribute("_cache_refresh", "true");
                final EbppxEcsUser ecsu = parseParam(req);
                // 0 for disabled, 1 for enabled
                String strEnableButton = "1";

                // if a session doesn't exist, sessionPrev is null
                final HttpSession sessionPrev = req.getSession(false);

                if (null != sessionPrev) {
                    try {
                        sessionPrev.invalidate();
                    } catch (IllegalStateException e) {
                        // Do nothing (session was already invalidated).
                    }
                }

                // create a new session, if one doesn't already exist.
                final HttpSession session = req.getSession(true);


				// Added to generate random keys
				String randomKey = EncryptionHelper.getUUID();
				// end added

                // place User object in session
                session.setAttribute(EbppxConstants.RANDOM_KEY, randomKey);
                session.setAttribute(EbppxConstants.ECS_USER, ecsu);
                session.setAttribute(EbppxConstants.USER_LOGGED_ON,"true");
                session.setAttribute(EbppxConstants.BUTTON_ENABLED,strEnableButton);
				//res.addHeader("P3P","CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\"");
				//redirect to next page
				redirectToMappedUrl(
				req,
				res,
				EbppxConstants.URL_MYBILLS_SUCCESS_PARAM,
				"");

            }
            catch (LogonException ex) {
                redirectToMappedUrl(
                req,
                res,
                EbppxConstants.URL_LOGON_FAILURE_PARAM,
                EbppxConstants.MESSAGE_0 + "=" + java.net.URLEncoder.encode(ex.getMessage()));
            }

            commitTransaction(req, fName);
            doPostTransaction(req, res);
        }
        catch (Throwable t) {
            throw new ServletException(t.toString(), t);
        }
        finally {
            rollbackTransaction(req, fName);
            deactivateISeriesEngine(req, fName);
        }

        if (trcLogger.isLogging())
            trcLogger.exit(IRecordType.TYPE_INFO, this, fName);
    }
}
